#pragma once
#include <any>
#include <utility>
#include <functional>
#include <iostream>
#include <any>
class AnyFunction
{
public:
	AnyFunction() : pointerOfObj_(nullptr), haveResult_(false), pointerOfResult_(nullptr){};
	~AnyFunction() {};

public:
	template<typename F, typename ...Args>
	void Load(F&& f, void* objPointer, bool haveResult, Args&&... args);
	void Call();
private:
	std::tuple<> args_;
	std::function<void()> func_;
	std::shared_ptr<std::any> pointerOfResult_;
	void* pointerOfObj_;
	bool haveResult_;
};

template<typename F, typename ...Args>
inline void AnyFunction::Load(F&& f, void* objPointer, bool haveResult, Args && ...args)
{
	haveResult_ = haveResult;
	pointerOfObj_ = objPointer;
	if (objPointer == nullptr && haveResult == false) {
		func_ = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
	}
	else if (objPointer == nullptr && haveResult == true) {
		func_ = [f, args...] mutable {
			auto res = f(args...);
			pointerOfResult_ = std::make_shared<std::any>(res);
		}
	}
	//else if (objPointer != nullptr && haveResult == false) {
	//	func_ = [&, std::forward<F>(f), objPointer, args...] mutable {
	//		objPointer.*f(args...);
	//	}
	//}
	//else {
	//	func_ = [&, std::forward<F>(f), objPointer, args...] mutable {
	//		auto res = objPointer.*f(args...);
	//		pointerOfResult_ = std::make_shared<std::any>(res);
	//	}
	//}
}
